from sqlalchemy.orm import Session
from sqlalchemy import desc
from typing import List, Optional
from models.ota import OTAFirmware
from schemas.ota import OTAFirmwareCreate, OTAFirmwareUpdate
import re


def compare_versions(version1: str, version2: str) -> int:
    """
    比较两个版本号
    返回: 1 如果 version1 > version2
          0 如果 version1 == version2  
         -1 如果 version1 < version2
    """
    def parse_version(version: str) -> List[int]:
        # 移除可能的 'v' 前缀
        version = version.lstrip('v')
        # 按点分割并转换为整数
        parts = version.split('.')
        # 确保每个部分都是0-255之间的整数
        result = []
        for part in parts:
            try:
                num = int(part)
                if num < 0 or num > 255:
                    num = 0  # 超出范围设为0
                result.append(num)
            except ValueError:
                result.append(0)
        # 补齐到3位
        while len(result) < 3:
            result.append(0)
        return result[:3]  # 只取前3位
    
    v1_parts = parse_version(version1)
    v2_parts = parse_version(version2)
    
    # 从高位到低位比较
    for i in range(3):
        if v1_parts[i] > v2_parts[i]:
            return 1
        elif v1_parts[i] < v2_parts[i]:
            return -1
    
    return 0


def create_ota_firmware(db: Session, firmware: OTAFirmwareCreate, cm3_file_info: Optional[dict] = None, dsp_file_info: Optional[dict] = None) -> OTAFirmware:
    """创建OTA固件记录"""
    db_firmware = OTAFirmware(
        cm3_version=firmware.cm3_version,
        cm3_version_code=firmware.cm3_version_code,
        cm3_changelog=firmware.cm3_changelog,
        dsp_version=firmware.dsp_version,
        dsp_version_code=firmware.dsp_version_code,
        dsp_changelog=firmware.dsp_changelog,
        remark=firmware.remark
    )
    
    # 设置CM3文件信息
    if cm3_file_info:
        db_firmware.cm3_file_name = cm3_file_info.get('file_name')
        db_firmware.cm3_file_path = cm3_file_info.get('file_path')
        db_firmware.cm3_file_size = cm3_file_info.get('file_size')
    
    # 设置DSP文件信息
    if dsp_file_info:
        db_firmware.dsp_file_name = dsp_file_info.get('file_name')
        db_firmware.dsp_file_path = dsp_file_info.get('file_path')
        db_firmware.dsp_file_size = dsp_file_info.get('file_size')
    
    db.add(db_firmware)
    db.commit()
    db.refresh(db_firmware)
    return db_firmware


def get_ota_firmware_by_id(db: Session, firmware_id: int) -> Optional[OTAFirmware]:
    """根据ID获取OTA固件"""
    return db.query(OTAFirmware).filter(OTAFirmware.id == firmware_id).first()


def get_latest_active_firmware(db: Session) -> Optional[OTAFirmware]:
    """获取最新的激活固件 - 按版本号和时间排序"""
    # 获取所有激活的固件
    firmwares = db.query(OTAFirmware).filter(
        OTAFirmware.is_active == True
    ).order_by(desc(OTAFirmware.created_at)).all()
    
    if not firmwares:
        return None
    
    # 按版本号排序，如果版本号相同则按时间排序
    latest_firmware = None
    latest_version = None
    
    for firmware in firmwares:
        # 检查CM3版本
        if firmware.cm3_version:
            if latest_firmware is None or compare_versions(firmware.cm3_version, latest_version) > 0:
                latest_firmware = firmware
                latest_version = firmware.cm3_version
        
        # 检查DSP版本
        if firmware.dsp_version:
            if latest_firmware is None or compare_versions(firmware.dsp_version, latest_version) > 0:
                latest_firmware = firmware
                latest_version = firmware.dsp_version
    
    return latest_firmware


def get_latest_cm3_firmware(db: Session) -> Optional[OTAFirmware]:
    """获取最新的CM3固件 - 按版本号排序"""
    # 获取所有包含CM3的激活固件
    firmwares = db.query(OTAFirmware).filter(
        OTAFirmware.is_active == True,
        OTAFirmware.cm3_version.isnot(None)
    ).order_by(desc(OTAFirmware.created_at)).all()
    
    if not firmwares:
        return None
    
    # 按CM3版本号排序
    latest_firmware = firmwares[0]
    latest_version = latest_firmware.cm3_version
    
    for firmware in firmwares[1:]:
        if compare_versions(firmware.cm3_version, latest_version) > 0:
            latest_firmware = firmware
            latest_version = firmware.cm3_version
    
    return latest_firmware


def get_latest_dsp_firmware(db: Session) -> Optional[OTAFirmware]:
    """获取最新的DSP固件 - 按版本号排序"""
    # 获取所有包含DSP的激活固件
    firmwares = db.query(OTAFirmware).filter(
        OTAFirmware.is_active == True,
        OTAFirmware.dsp_version.isnot(None)
    ).order_by(desc(OTAFirmware.created_at)).all()
    
    if not firmwares:
        return None
    
    # 按DSP版本号排序
    latest_firmware = firmwares[0]
    latest_version = latest_firmware.dsp_version
    
    for firmware in firmwares[1:]:
        if compare_versions(firmware.dsp_version, latest_version) > 0:
            latest_firmware = firmware
            latest_version = firmware.dsp_version
    
    return latest_firmware


def get_firmware_list(db: Session, skip: int = 0, limit: int = 100) -> List[OTAFirmware]:
    """获取固件列表"""
    return db.query(OTAFirmware).order_by(desc(OTAFirmware.created_at)).offset(skip).limit(limit).all()


def get_firmware_count(db: Session) -> int:
    """获取固件总数"""
    return db.query(OTAFirmware).count()


def update_ota_firmware(db: Session, firmware_id: int, firmware_update: OTAFirmwareUpdate) -> Optional[OTAFirmware]:
    """更新OTA固件"""
    db_firmware = get_ota_firmware_by_id(db, firmware_id)
    if not db_firmware:
        return None
    
    update_data = firmware_update.dict(exclude_unset=True)
    for field, value in update_data.items():
        setattr(db_firmware, field, value)
    
    db.commit()
    db.refresh(db_firmware)
    return db_firmware


def delete_ota_firmware(db: Session, firmware_id: int) -> bool:
    """删除OTA固件"""
    db_firmware = get_ota_firmware_by_id(db, firmware_id)
    if not db_firmware:
        return False
    
    db.delete(db_firmware)
    db.commit()
    return True


def get_latest_firmware_versions(db: Session) -> dict:
    """获取最新固件版本信息"""
    firmware = get_latest_active_firmware(db)
    
    if not firmware:
        return {"cm3": None, "dsp": None}
    
    cm3_info = None
    dsp_info = None
    
    if firmware.cm3_version:
        cm3_info = {
            "version": firmware.cm3_version,
            "version_code": firmware.cm3_version_code,
            "file_name": firmware.cm3_file_name,
            "file_path": firmware.cm3_file_path,
            "file_size": firmware.cm3_file_size,
            "changelog": firmware.cm3_changelog
        }
    
    if firmware.dsp_version:
        dsp_info = {
            "version": firmware.dsp_version,
            "version_code": firmware.dsp_version_code,
            "file_name": firmware.dsp_file_name,
            "file_path": firmware.dsp_file_path,
            "file_size": firmware.dsp_file_size,
            "changelog": firmware.dsp_changelog
        }
    
    return {
        "cm3": cm3_info,
        "dsp": dsp_info
    } 